﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NPlot;

namespace CM1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int FuncType = 0, GuType = 0;
            int n = 0;

            //Узнать тип функции
            string a = this.listBox1.Text;

            if (a == "Тестовая функция")
            { FuncType = 1; }
            if (a == "f(x) = sqrt(x) * cos(x)")
            { FuncType = 2; }
            if (a == "f(x) + cos(10x)")
            { FuncType = 3; }
            if (a == "f(x) + cos(100x)")
            { FuncType = 4; }

            //Число разбиений
            n = Convert.ToInt32(this.textBox1.Text);

            //Узнать тип граничных условий
            if (this.radioButton1.Checked) GuType = 1;
            if (this.radioButton2.Checked) GuType = 2;


            //Забить в сплай значения
            Spline A = null;
            A = new Spline();
            A.CSpline(n, GuType, FuncType);

            //Построить сплайн 
            A.ComputeSpline();

            //Вывод коэфф сплайна на экран
            for (int i = 1; i < n; i++)
            {
                dataGridView1.Rows.Add();
                dataGridView1.Rows[i - 1].Cells[0].Value = Convert.ToString(i);
                dataGridView1.Rows[i - 1].Cells[1].Value = A.a[i].ToString("G4");
                dataGridView1.Rows[i - 1].Cells[2].Value = A.b[i].ToString("G4");
                dataGridView1.Rows[i - 1].Cells[3].Value = A.c[i].ToString("G4");
                dataGridView1.Rows[i - 1].Cells[4].Value = A.d[i].ToString("G4");
            }

            //Определение максимальной погрешности функции, производной и
            //аргументов на которых это происходит и вывод на экран
            double arg = -100, argPr = -100;
            double val = -1, valPr = -1;
            for (int i = 0; i < 2 * n; i++)
            {
                double x = 0.0;
                if (FuncType == 1) { x = -1.0 + 2.0 * i / (2 * n - 1); }
                else { x = 1 + 2.1415926535897932384626433832795 * i / (2.0 * n - 1); }

                double currVal = System.Math.Abs(A.CompSplineVal(x) - A.ComputeFunc(x,FuncType));
                double Fpr = A.ComputePrFunc(x,FuncType);
                double Spr = A.CompSplineValPr(x);
                double currValPr = System.Math.Abs(Fpr - Spr);
                dataGridView2.Rows.Add();
                dataGridView2.Rows[i].Cells[0].Value = Convert.ToString(i + 1);
                dataGridView2.Rows[i].Cells[1].Value = x.ToString("G4");
                dataGridView2.Rows[i].Cells[2].Value = A.ComputeFunc(x,FuncType).ToString("G4");
                dataGridView2.Rows[i].Cells[3].Value = A.CompSplineVal(x).ToString("G4");
                dataGridView2.Rows[i].Cells[4].Value = currVal.ToString("e3");
                dataGridView2.Rows[i].Cells[5].Value = Fpr.ToString("G4");
                dataGridView2.Rows[i].Cells[6].Value = Spr.ToString("G4");
                dataGridView2.Rows[i].Cells[7].Value = currValPr.ToString("e3");
                if (currVal > val)
                {
                    val = currVal;
                    arg = x;
                }
                if (currValPr > valPr)
                {
                    valPr = currValPr;
                    argPr = x;
                }
            }

            //Вывод на экран макс погрешности
            textBox2.Text = val.ToString("e2");
            textBox4.Text = arg.ToString("G4");
            textBox3.Text = valPr.ToString("e2");
            textBox5.Text = argPr.ToString("G4");

            // Вывод графики на экран
            // пусть для вывода используется 2к шагов
            if (radioButton3.Checked)
            {
                this.plotSurface2D1.Clear();
                double[] Agrx = new double[2000];
                double[] Sy = new double[2000];
                double[] Fy = new double[2000];
                for (int i = 0; i < 2000; i++)
                {
                    if (FuncType == 1) { Agrx[i] = -1.0 + 2.0 * i / 2000; }
                    else Agrx[i] = 1 + 2.1415926535897932384626433832795 * i / 2000;
                    Fy[i] = A.ComputeFunc(Agrx[i],FuncType);
                    Sy[i] = A.CompSplineVal(Agrx[i]);
                }

                LinePlot lp = new LinePlot();
                lp.OrdinateData = Fy;
                lp.AbscissaData = Agrx;
                lp.Pen = new Pen(Color.Red, 1.0f);
                plotSurface2D1.Add(lp);
                this.plotSurface2D1.Refresh();
                LinePlot lp2 = new LinePlot();
                lp2.OrdinateData = Sy;
                lp2.AbscissaData = Agrx;
                lp2.Pen = new Pen(Color.Black, 1.0f);
                plotSurface2D1.Add(lp2);
                this.plotSurface2D1.Refresh();
            }
            if (radioButton4.Checked)
            {
                this.plotSurface2D1.Clear();
                double[] Agrx = new double[2000];
                double[] Sy = new double[2000];
                double[] Fy = new double[2000];
                for (int i = 0; i < 2000; i++)
                {
                    if (FuncType == 1) { Agrx[i] = -1.0 + 2.0 * i / 2000.0; }
                    else Agrx[i] = 1.0 + 2.1415926535897932384626433832795 * i / 2000.0;
                    Fy[i] = A.ComputePrFunc(Agrx[i],FuncType);
                    Sy[i] = A.CompSplineValPr(Agrx[i]);
                }

                LinePlot lp = new LinePlot();
                lp.OrdinateData = Fy;
                lp.AbscissaData = Agrx;
                lp.Pen = new Pen(Color.Red, 1.0f);
                plotSurface2D1.Add(lp);
                this.plotSurface2D1.Refresh();
                LinePlot lp2 = new LinePlot();
                lp2.OrdinateData = Sy;
                lp2.AbscissaData = Agrx;
                lp2.Pen = new Pen(Color.Black, 1.0f);
                plotSurface2D1.Add(lp2);
                this.plotSurface2D1.Refresh();
            }
        }
    }
}
